package cn.org.wangchangjiu.redis.delay;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * *
 *  * @Classname DelayQueueAutoConfig
 *  * @Description
 *  * @Date 2022/9/14 10:20
 *  * @Created by wangchangjiu
 */
@Configuration
@EnableConfigurationProperties({ RedisDelayProperties.class })
@ConditionalOnProperty(value = "redis.util.delay.enable", havingValue = "true" )
public class DelayQueueAutoConfiguration {


    @Autowired
    private RedisDelayProperties properties;

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setDefaultSerializer(deserializer());
        template.setKeySerializer(new StringRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    private GenericJackson2JsonRedisSerializer deserializer() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        return new GenericJackson2JsonRedisSerializer(mapper);
    }

    @Bean
    @ConditionalOnMissingBean(DelayQueue.class)
    public DelayQueue delayQueueMessage(@Autowired RedisTemplate<String, Object> redisTemplate){
        return new RedisDelayQueue(redisTemplate, properties);
    }


    @Bean
    @ConditionalOnMissingBean(DelayQueueMessageProducer.class)
    @DependsOn({"delayQueueMessage"})
    public DelayQueueMessageProducer delayQueueMessageProducer(@Autowired DelayQueue delayQueueMessage){
        return new DelayQueueMessageProducer(delayQueueMessage, properties.getRegisterService());
    }

    @Bean
    @ConditionalOnMissingBean(DelayQueueMessageConsumer.class)
    @DependsOn({"delayQueueMessage"})
    public DelayQueueMessageConsumer delayQueueMessageConsumer(@Autowired DelayQueue delayQueueMessage){
        return new DelayQueueMessageConsumer(delayQueueMessage, properties);
    }

}
